home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / stv.lha / STV / st_v / util / STVUTIL4.ZIP / OPNLNK.ZIP / ODBCINTR.PRJ next >
Text File  |  1993-01-04  |  65KB  |  1,941 lines

  1. "
  2. ******************************************************************************
  3. Application : ODBC Interface
  4. Date        : Jan  4, 1993
  5. Time        : 20:12:45
  6.  
  7. Invoked By:
  8. ===========
  9.  
  10.  
  11.  
  12.  
  13.  
  14. Description
  15. ===========
  16.  
  17. Classes : 
  18.     SQLStatement SQLConnection SQLEnvironment 
  19.     SQLObject SQLColumns ODBCDLL 
  20.  
  21. Methods : 
  22.     #startUp defined in SystemDictionary.
  23.     #fromAddress:length: defined in Integer class.
  24.     #fromAddress: defined in Float class.
  25.  
  26. ******************************************************************************
  27. "!
  28.  
  29. "Initialize"
  30.   
  31. Smalltalk at:#SQLInfoConstants
  32.     ifAbsent: [Smalltalk at:#SQLInfoConstants put: Dictionary new].
  33. !
  34.  
  35. "This application adds or changes methods of class Float
  36.  The class should already exist in the system.
  37. Number variableByteSubclass: #Float
  38.   classVariableNames: ''
  39.   poolDictionaries: '' "!
  40.  
  41. Object subclass: #SQLObject
  42.   instanceVariableNames: ''
  43.   classVariableNames: ''
  44.   poolDictionaries: ''!
  45.  
  46. "This application adds or changes methods of class SystemDictionary
  47.  The class should already exist in the system.
  48. Dictionary subclass: #SystemDictionary
  49.   instanceVariableNames: ''
  50.   classVariableNames: 
  51.     'StartUpObjects ExitObjects '
  52.   poolDictionaries: 
  53.     'FileConstants WinConstants CharacterConstants ' "!
  54.  
  55. "This application adds or changes methods of class Integer
  56.  The class should already exist in the system.
  57. Number subclass: #Integer
  58.   instanceVariableNames: ''
  59.   classVariableNames: ''
  60.   poolDictionaries: '' "!
  61.  
  62. SQLObject subclass: #SQLColumns
  63.   instanceVariableNames: 
  64.     'statement collection '
  65.   classVariableNames: ''
  66.   poolDictionaries: ''!
  67.  
  68. DynamicLinkLibrary variableByteSubclass: #ODBCDLL
  69.   classVariableNames: ''
  70.   poolDictionaries: ''!
  71.  
  72. SQLObject subclass: #SQLStatement
  73.   instanceVariableNames: 
  74.     'connection hstmt params columns '
  75.   classVariableNames: ''
  76.   poolDictionaries: ''!
  77.  
  78. SQLObject subclass: #SQLConnection
  79.   instanceVariableNames: 
  80.     'environment hdbc statements '
  81.   classVariableNames: ''
  82.   poolDictionaries: 
  83.     'SQLInfoConstants '!
  84.  
  85. SQLObject subclass: #SQLEnvironment
  86.   instanceVariableNames: 
  87.     'henv connections '
  88.   classVariableNames: ''
  89.   poolDictionaries: ''!
  90.  
  91.  
  92.  
  93. !SQLStatement class methods !
  94.  
  95. allocateOn: con
  96.     "Private"
  97.     ^super new connection: con; allocate.! !
  98.  
  99.  
  100.  
  101. !SQLStatement methods !
  102.  
  103. allocate
  104.     "Private"
  105.     | address |
  106.     address := WinAddress allocateMemory: 4.
  107.     (ODBCLibrary SQLAllocStmt: (connection handle asParameter)
  108.         with: address asParameter) ~= SQLObject success
  109.         ifTrue: [address unlockAndFree. ^nil]
  110.         ifFalse: [
  111.             self handle: (WinLong fromAddress: address).
  112.             address unlockAndFree.
  113.             params := OrderedCollection new.
  114.              ^self].!
  115.    
  116. allocateColumns
  117.     "Allocate columns for retrieving results,
  118.     then describe and bind  all columns.
  119.     Asnwer an instnace of SQLColumns."
  120.  
  121.     columns := SQLColumns allocateOn: self.
  122.     ^columns allocate: self numberOfResultColumns.!
  123.  
  124. cancel
  125.     "Cancel the execution of the statement of the receiver."
  126.  
  127.     ((ODBCLibrary SQLCancel: self handle asParameter) ~= self class success)
  128.         ifTrue: [^nil]!
  129.    
  130. close
  131.     "Close the cursor and abandon all the pending results."
  132.  
  133.     ^self free: (SQLObject close)!
  134.  
  135. columnPrivilegesWithTableQualifer: aTableQualifier
  136.         tableOwner: aTableOwner
  137.         tableName: aTableName
  138.         columnName: searchPatternForColumnNames
  139.  
  140.     "Returns a list of columns and associated privileges for one or more tables as a resut"
  141.  
  142.     ((ODBCLibrary SQLColumnPrivileges: self handle asParameter
  143.         with: aTableQualifier asParameter
  144.         with: aTableQualifier size asParameter
  145.         with: aTableOwner asParameter
  146.         with: aTableOwner size asParameter
  147.         with: aTableName asParameter
  148.         with: aTableName size asParameter
  149.         with: searchPatternForColumnNames asParameter
  150.         with: searchPatternForColumnNames size asParameter) ~= self class success)
  151.         ifTrue: [^nil]!
  152.  
  153. columns
  154.  
  155.     "Private"
  156.  
  157.     ^columns!
  158.    
  159. columns: aColumns
  160.  
  161.     "Private"
  162.  
  163.     columns := aColumns!
  164.   
  165. columnsWithTableQualifer: aTableQualifier
  166.         tableOwner: searchPatternForTableOwner
  167.         tableName: searchPatternForTableName
  168.         columnName: searchPatternForColumnNames
  169.  
  170.     "Returns the list of column names in specified tables as a result."
  171.  
  172.     ((ODBCLibrary SQLColumns: self handle asParameter
  173.         with: aTableQualifier asParameter
  174.         with: aTableQualifier size asParameter
  175.         with: searchPatternForTableOwner asParameter
  176.         with: searchPatternForTableOwner size asParameter
  177.         with: searchPatternForTableName asParameter
  178.         with: searchPatternForTableName size asParameter
  179.         with: searchPatternForColumnNames asParameter
  180.         with: searchPatternForColumnNames size asParameter) ~= self class success)
  181.         ifTrue: [^nil]!
  182.  
  183. connection
  184.  
  185.     "Private"
  186.  
  187.     ^connection!
  188.  
  189. connection: aConnection
  190.     "Private"
  191.  
  192.     connection := aConnection.
  193.     ^self!
  194.  
  195. describeParameterAt: aMarkerNumber
  196.  
  197.     "Private"
  198.  
  199.     self error: ''!
  200.   
  201. Doit      self drop!
  202.  
  203. drop
  204.     "Close the cursor and abandon all the pending results
  205.     and free all the memory space allocated by teh receiver."
  206.  
  207.     self free: (SQLObject drop)!
  208.   
  209. execute
  210.     "Execute the prepated statements.
  211.     Ansewer nil if failed or something is wrong."
  212.  
  213.     ((ODBCLibrary SQLExecute: self handle asParameter) ~= self class success)
  214.         ifTrue: [^nil]!
  215.  
  216. executeDirect: aStatement
  217.     "Execute aStatement directly
  218.     Ansewer nil if failed or something is wrong."
  219.  
  220.     ((ODBCLibrary SQLExecDirect: self handle asParameter with: aStatement asParameter
  221.         with: aStatement size asParameter) ~= self class success)
  222.         ifTrue: [^nil].!
  223.  
  224. foreignKeys: aPrimaryKeyTableQualifier
  225.     with: aPrimaryKeyOwnerName
  226.     with: aPrimaryKeyTableName
  227.     with: aForeignKeyTableQualifier
  228.     with: aForeignKeyOwnerName
  229.     with: aMatchForeignKeyTableName
  230.  
  231.    "Private"
  232.  
  233.     ODBCLibrary SQLForeignKeys: self handle asParameter
  234.         with: aPrimaryKeyOwnerName asParameter
  235.         with: aPrimaryKeyOwnerName size asParameter
  236.         with: aPrimaryKeyTableName asParameter
  237.         with: aPrimaryKeyTableName size asParameter
  238.         with: aForeignKeyTableQualifier asParameter
  239.         with: aForeignKeyTableQualifier size asParameter
  240.         with: aForeignKeyOwnerName asParameter
  241.         with: aForeignKeyOwnerName size asParameter
  242.         with: aMatchForeignKeyTableName asParameter
  243.         with: aMatchForeignKeyTableName size asParameter!
  244.    
  245. free: anOption
  246.     "Private"
  247.     (self handle = nil)
  248.         ifTrue: [^self error: 'Already released.'].
  249.     ((ODBCLibrary SQLFreeStmt: self handle asParameter
  250.             with: anOption asParameter) ~= self class success)
  251.         ifTrue: [^nil].
  252.     (anOption = self class close)
  253.         ifTrue: [
  254.             params do: [ :address | address unlockAndFree].
  255.             params := OrderedCollection new.
  256.             columns notNil ifTrue: [columns free. columns := nil]]
  257.         ifFalse: [
  258.             params do: [ :address | address unlockAndFree]. params := nil.
  259.             columns notNil ifTrue: [columns free. columns := nil].
  260.             connection remove: self.
  261.             self handle: nil].!
  262.  
  263. getAllTypes
  264.  
  265.     "Returns information about all data types supported by the data source as a result."
  266.  
  267.     ^self getTypeInformation: SQLObject allTypes!
  268.  
  269. getCursorName
  270.     "Answer the cursor name assigned with the receiver"
  271.     | addressOfCursorName addressOfNumberOfBytes cursorName |
  272.     addressOfCursorName := WinAddress allocateMemory: SQLObject bufferSizeForName.
  273.     addressOfNumberOfBytes := WinAddress allocateMemory: 2.
  274.     ODBCLibrary SQLGetCursorName: self handle asParameter
  275.         with: addressOfCursorName asParameter
  276.         with: SQLObject bufferSizeForName asParameter
  277.         with: addressOfNumberOfBytes asParameter.
  278.     cursorName := String fromAddress: addressOfCursorName
  279.         length: (WinLong fromAddress: addressOfNumberOfBytes) asInteger.
  280.     addressOfCursorName unlockAndFree.
  281.     addressOfNumberOfBytes unlockAndFree.
  282.     ^cursorName.!
  283.    
  284. getStatementOption: anOptionToRetroeve
  285.     "Private"
  286.  
  287.     | addressOfValueOfOption valueOfOption |
  288.     addressOfValueOfOption := WinAddress allocateMemory: 4.
  289.     ODBCLibrary SQLGetStmtOption: self handle asParameter
  290.         with: anOptionToRetroeve asParameter
  291.         with: addressOfValueOfOption.
  292.     valueOfOption := (WinLong fromAddress: addressOfValueOfOption) asInteger.
  293.     addressOfValueOfOption unlockAndFree.
  294.     ^valueOfOption.!
  295.   
  296. getTypeInformation: aDataTypeNumber
  297.     "Private"
  298.  
  299.     ((ODBCLibrary SQLGetTypeInfo: self handle asParameter
  300.         with: aDataTypeNumber asParameter) ~= self class success)
  301.         ifTrue: [^nil]!
  302.  
  303. handle
  304.     "Private"
  305.  
  306.     ^hstmt!
  307.  
  308. handle: aHandle
  309.     "Private"
  310.  
  311.     hstmt := aHandle!
  312.  
  313. moreResults
  314.     "Private"
  315.  
  316.     ODBCLibrary SQLMoreResults: self handle asParameter.!
  317.  
  318. numberOfParameters
  319.     "Private"
  320.  
  321.     | numberOfParameters addressOfNumberOfParameters |
  322.  
  323.     addressOfNumberOfParameters := WinAddress allocateMemory: 2.
  324.     ODBCLibrary SQLNumParams: self handles asParameter
  325.         with: addressOfNumberOfParameters asParameter.
  326.  
  327.     numberOfParameters := (WinLong fromAddress: addressOfNumberOfParameters) asInteger.
  328.     addressOfNumberOfParameters unlockAndFree.
  329.     ^addressOfNumberOfParameters!
  330.    
  331. numberOfResultColumns
  332.     "Answer an number of columns in the result."
  333.     "Private"
  334.  
  335.     | numberOfColumns addressOfNumberOfColumns |
  336.  
  337.     addressOfNumberOfColumns := WinAddress allocateMemory: 4.
  338.     ODBCLibrary SQLNumResultCols: self handle asParameter
  339.         with: addressOfNumberOfColumns asParameter.
  340.     numberOfColumns := (WinLong fromAddress: addressOfNumberOfColumns) asInteger.
  341.     addressOfNumberOfColumns unlockAndFree.
  342.     ^numberOfColumns.!
  343.  
  344. parameterData
  345.     "Private"
  346.    self error: ''.!
  347.    
  348. parameterOptions
  349.     "Private"
  350.     self error: ''.!
  351.    
  352. prepare: aStatement
  353.     "Prepare aStatement for the execution"
  354.  
  355.     ((ODBCLibrary SQLPrepare: self handle asParameter
  356.         with: aStatement asParameter
  357.         with: aStatement size asParameter) ~= self class success)
  358.         ifTrue: [^nil]!
  359.   
  360. primaryKeys: aQualifierName
  361.     with: aSearchPatternForOwnerName
  362.     with: aSearchPatternForTableName
  363.  
  364.     "Private"
  365.     ODBCLibrary SQLPrimaryKeys: self handle asParameter
  366.         with: aQualifierName asParameter
  367.         with: aQualifierName size asParameter
  368.         with: aSearchPatternForOwnerName asParameter
  369.         with: aSearchPatternForOwnerName size asParameter
  370.         with: aSearchPatternForTableName asParameter
  371.         with: aSearchPatternForTableName size asParameter.!
  372.   
  373. rowCount
  374.     "In the case of UPDATE, INSERT and DELETE,
  375.     answer an number of rows which were reflected by the execution."
  376.     | address count |
  377.     address := WinAddress allocateMemory: 4.
  378.     ODBCLibrary SQLRowCount: self handle asParameter
  379.         with: address asParameter.
  380.     count := Integer fromAddress: address length: 4.
  381.     address unlockAndFree.
  382.     ^count.!
  383.    
  384. setCursorName: aName
  385.  
  386.     "Associates aName with the cursor."
  387.  
  388.     ((ODBCLibrary SQLSetCursorName: self handle asParameter
  389.         with: aName asParameter
  390.         with: aName size asParameter) ~= self class success)
  391.         ifTrue: [^nil]!
  392.   
  393. setParameterAt: aNumber put: anObject
  394.  
  395.     "Assign anObject to the parameter marker in the statement.
  396.     The parameter marker is numbered from 1 in the left-to-right order"
  397.  
  398.     | address addressOfNumberOfBytes return numberOfBytes |
  399.     address := SQLObject assignBufferFor: anObject.
  400.     addressOfNumberOfBytes := WinAddress allocateMemory: 4.
  401.     addressOfNumberOfBytes at: 1 put: (anObject size).
  402.     params add: address; add: addressOfNumberOfBytes.
  403.     return := ODBCLibrary SQLSetParam: self handle asParameter
  404.         with: aNumber asParameter
  405.         with: (SQLObject cTypeFor: anObject class) asParameter
  406.         with: (SQLObject sqlTypeFor: anObject class) asParameter
  407.         with: anObject size asParameter
  408.         with: 0 asParameter
  409.         with: address asParameter
  410.         with: addressOfNumberOfBytes asParameter.
  411.     numberOfBytes :=
  412.         Integer fromAddress: addressOfNumberOfBytes length: 4.
  413.     (return ~= self class success)
  414.         ifTrue: [^nil] ifFalse: [^numberOfBytes]!
  415.   
  416. setPositionAt: anAbsolutePositionOfCursor
  417.     refresh: anOptionForRefresh lock: anOptionForLock
  418.     "Private"
  419.     ODBCLibrary SQLSetPos: self handle asParamter
  420.         with: anOptionForRefresh asParameter
  421.         with: anOptionForLock asParameter.!
  422.    
  423. tablePrivilegesWithQualifier: aTableQualifier
  424.         owner: searchPatternForOwners
  425.         name: searchPatternForNames
  426.  
  427.     "Returns a list of tables and the privileges as a result."
  428.  
  429.     ((ODBCLibrary SQLTablePrivileges: self handle asParameter
  430.         with: aTableQualifier asParameter
  431.         with: aTableQualifier size asParameter
  432.         with: searchPatternForOwners asParameter
  433.         with: searchPatternForOwners size asParameter
  434.         with: searchPatternForNames asParameter
  435.         with: searchPatternForNames size asParameter) ~= self class success)
  436.         ifTrue: [^nil]!
  437.  
  438. tablesWithQualifier: searchPatternForQualifiers
  439.    owner: searchPatternForOwners
  440.     name: searchPatternForNames
  441.     type: listOfTableTypesToMatch
  442.  
  443.     "Returns the list of tables names as a result."
  444.  
  445.     ((ODBCLibrary SQLTables: self handle asParameter
  446.         with: searchPatternForQualifiers asParameter
  447.         with: searchPatternForQualifiers size asParameter
  448.         with: searchPatternForOwners asParameter
  449.         with: searchPatternForOwners size asParameter
  450.         with: searchPatternForNames asParameter
  451.         with: searchPatternForNames size asParameter
  452.         with: listOfTableTypesToMatch asParameter
  453.         with: listOfTableTypesToMatch size asParameter) ~= self class success)
  454.         ifTrue: [^nil]! !
  455.  
  456.  
  457.  
  458. !SQLConnection class methods !
  459.    
  460. allocateOn: env
  461.     "Private"
  462.  
  463.     ^super new environment: env; allocate! !
  464.  
  465.  
  466.  
  467. !SQLConnection methods !
  468.   
  469. allocate
  470.     | address |
  471.     "Private"
  472.     address := WinAddress allocateMemory: 4.
  473.     (ODBCLibrary SQLAllocConnect: (environment handle asParameter)
  474.         with: address asParameter) ~= SQLObject success
  475.         ifTrue: [address unlockAndFree. ^nil]
  476.         ifFalse: [
  477.             self handle: (WinLong fromAddress: address).
  478.             statements := OrderedCollection new.
  479.             address unlockAndFree.
  480.             ^self].!
  481.  
  482. allocateStatement
  483.     "Allocate an statement related to the receiver and
  484.      answer an instance of SQLStatement.
  485.     Answers nil if an statement could not be allocated."
  486.     | statement |
  487.     (statement := SQLStatement allocateOn: self) notNil
  488.         ifTrue: [statements add: statement.  ^statement]
  489.         ifFalse: [^nil].!
  490.   
  491. commitTransaction
  492.     "Commit all the transaction including UPDATE,INSERT and DELETE
  493.     which were executed after the connection, the last commitment or
  494.     the last rollback.
  495.     Answers nil if failed"
  496.     ^self transaction: (SQLObject commit)!
  497.  
  498. connectServer: aServerName user: aUserName
  499.     password: aPassword
  500.     "Establish an connection with the taget SQL server.
  501.     Answer nil if failed"
  502.     | returnCode |
  503.     returnCode := ODBCLibrary SQLConnect: self handle asParameter
  504.         with: aServerName asParameter
  505.         with: aServerName size asParameter
  506.         with: aUserName asParameter
  507.         with: aUserName size asParameter
  508.         with: aPassword asParameter
  509.         with: aPassword size asParameter.
  510.     ((returnCode == (SQLObject success)) or: [returnCode == (SQLObject successWithInfo)])
  511.                 ifFalse: [^nil]!
  512.    
  513. disconnect
  514.     "Close the connection"
  515.  
  516.     ODBCLibrary SQLDisconnect: self handle asParameter!
  517.    
  518. driverConnect: aFullConnectionString
  519.     "Private"
  520.     self error: ''.!
  521.    
  522. environment
  523.     "Private"
  524.  
  525.     ^environment!
  526.  
  527. environment: env
  528.     "Private"
  529.     environment := env.
  530.     ^self!
  531.  
  532. free
  533.  
  534.     "Release all the memory space allocated by the receiver
  535.     and free all statements which are allocted by the receiver."
  536.     (self handle = nil)
  537.         ifTrue: [^self error: 'Already released.'].
  538.     statements do: [ :statement |
  539.         statement  ~= nil ifTrue: [statement  drop]].
  540.     statements := nil.
  541.     environment remove: self.
  542.     self disconnect.
  543.     ODBCLibrary SQLFreeConnect: self handle asParameter.
  544.     self handle: nil.!
  545.  
  546. getConnectionOption: anOptionToRetrieve
  547.     "Private"
  548.  
  549.     | addressOfAssociatedWithOption associatedWithOption |
  550.     addressOfAssociatedWithOption := WinAddress allocateMemory: 4.
  551.     ODBCLibrary SQLGetConnectOption: self handle asParameter
  552.         with: anOptionToRetrieve asParameter
  553.         with: addressOfAssociatedWithOption.
  554.     associatedWithOption := (WinLong fromAddress: addressOfAssociatedWithOption) asInteger.
  555.     addressOfAssociatedWithOption unlockAndFree.
  556.     ^associatedWithOption!
  557.    
  558. getFunction: aFunctionNumberOfInterest
  559.     "Private"
  560.  
  561.     | addressOfExisits exisits |
  562.     addressOfExisits := WinAddress allocateMemory: 4.
  563.     ODBCLibrary SQLGetFunctions: self handle asParameter
  564.         with: aFunctionNumberOfInterest asParameter
  565.         with: addressOfExisits.
  566.     exisits :=  (WinLong fromAddress: addressOfExisits) asInteger.
  567.     addressOfExisits unlockAndFree.
  568.     exisits == (SQLObject true)
  569.         ifTrue: [^true]
  570.         ifFalse: [^false].!
  571.  
  572. getInformation
  573.     "Answer general information about the drivers and data sources
  574.     associated with the receiver"
  575.  
  576.     | information id |
  577.     information := Dictionary new.
  578.     SQLInfoConstants keysDo: [ :key |
  579.         id := SQLInfoConstants at: key.
  580.         information at: key put: (self getInformationAbout: id)].
  581.     ^information!
  582.    
  583. getInformationAbout: anInformationType
  584.     "Private"
  585.  
  586.     | setOfStringType |
  587.     setOfStringType := #( 2 6 7 10 11 13 14 16 17 18 19 20 25 27 29 36 37 38 39 40 41 42 45 47  ) asSet.
  588.     (setOfStringType includes: anInformationType)
  589.         ifTrue: [
  590.             ^self getInformationAbout: anInformationType size: SQLObject bufferSizeForName
  591.                 asString: true]
  592.         ifFalse: [^self getInformationAbout: anInformationType size: 4 asString: false].!
  593.  
  594. getInformationAbout: anInformationType size: aSize asString: asString
  595.     "Private"
  596.     | addressOfInformation addressOfNumberOfBytes information |
  597.     addressOfInformation := WinAddress allocateMemory: aSize.
  598.     addressOfNumberOfBytes := WinAddress allocateMemory: 2.
  599.     ODBCLibrary SQLGetInfo: self handle asParameter
  600.         with: anInformationType asParameter
  601.         with: addressOfInformation asParameter
  602.         with: SQLObject bufferSizeForName asParameter
  603.         with: addressOfNumberOfBytes asParameter.
  604.     asString
  605.         ifTrue: [
  606.             information := String fromAddress: addressOfInformation
  607.                 length: (Integer fromAddress: addressOfNumberOfBytes length: 2)]
  608.         ifFalse: [
  609.             information := Integer fromAddress: addressOfInformation
  610.                 length: (Integer fromAddress: addressOfNumberOfBytes length: 2)].
  611.     addressOfInformation unlockAndFree.
  612.     addressOfNumberOfBytes unlockAndFree.
  613.     ^information.!
  614.   
  615. handle
  616.  
  617.     ^hdbc!
  618.  
  619. handle: aHandle
  620.  
  621.     hdbc := aHandle!
  622.  
  623. nativeSQL: aSQLStatementToBeTranslated
  624.  
  625.     | addressOfAvailableBytes addressOfTranslatedSQLStatement
  626.     availableBytes translatedSQLStatement |
  627.  
  628.     addressOfTranslatedSQLStatement := WinAddress allocateMemory: SQLObject bufferSizeForName.
  629.     addressOfAvailableBytes := WinAddress allocateMemory: 4.
  630.     ODBCLibrary SQLNativeSql: self handle asParameter
  631.         with: aSQLStatementToBeTranslated asParameter
  632.         with: aSQLStatementToBeTranslated size asParameter
  633.         with: addressOfTranslatedSQLStatement asParameter
  634.         with: SQLObject bufferSizeForName asparameter
  635.         with: addressOfAvailableBytes asParameter.
  636.     availableBytes := (WinLong fromAddress:  addressOfAvailableBytes) asInteger.
  637.     availableBytes > (SQLObject bufferSizeForName)
  638.         ifTrue: [self errorOnReturnedStringIsTooLong].
  639.     translatedSQLStatement := String fromAddress: addressOfTranslatedSQLStatement.
  640.     addressOfAvailableBytes unlockAndFree.
  641.     addressOfTranslatedSQLStatement unlockAndFree.
  642.     ^translatedSQLStatement.!
  643.    
  644. remove: aStatement
  645.     "Private"
  646.     statements remove: aStatement.!
  647.   
  648. rollbackTransaction
  649.     "Rollback all the transaction including UPDATE,INSERT and DELETE
  650.     which were executed after the connection, the last commitment or
  651.     the last rollback.
  652.     Answers nil if failed"
  653.     self transaction: (SQLObject rollback)!
  654.  
  655. set
  656.     "Let the receiver an active server connection"
  657.  
  658.     self error: 'This API is not supported by ODBC.'!
  659.  
  660. setConnectionOption: anOptionToSet with: aValueOfOption
  661.  
  662.     ODBCLibrary SQLSetConnectOption: self handle asParameter
  663.         with: anOptionToSet asParameter
  664.         with: aValueOfOption asParameter.!
  665.  
  666. transaction: aType
  667.  
  668.     (ODBCLibrary SQLTransact: environment handle asParameter
  669.         with: self handle asParameter
  670.         with: aType asParameter) ~= SQLObject success
  671.         ifTrue: [^nil]! !
  672.  
  673.  
  674.  
  675. !SQLEnvironment class methods !
  676.   
  677. allocate
  678.     "Allocate an environment for SQL access and
  679.     answer an new instance of SQLEnvironment.
  680.     Answers ni if SQL environment could not be allocated."
  681.     ^self new allocate.! !
  682.  
  683.  
  684.  
  685. !SQLEnvironment methods !
  686.    
  687. allocate
  688.     "Private"
  689.     | address |
  690.     address := WinAddress allocateMemory: 4.
  691.     ((ODBCLibrary SQLAllocEnv: address asParameter) ~= SQLObject success)
  692.         ifTrue: [^nil].
  693.     self handle: (WinLong fromAddress: address).
  694.     address unlockAndFree.
  695.     connections := OrderedCollection new.
  696.     ^self.!
  697.  
  698. allocateConnection
  699.     "Allocate an connection related to the receiver and
  700.      answer an instance of SQLConnection.
  701.     Answers nil if the receiver could not allocate an connection"
  702.     | connect |
  703.     (connect := SQLConnection allocateOn: self) notNil
  704.         ifTrue: [connections add: connect. ^connect]
  705.         ifFalse: [^nil].!
  706.  
  707. connections
  708.     "Private"
  709.     ^connections!
  710.    
  711. dataSources
  712.     "Answer a dictionary of available data sources"
  713.  
  714.     | dictionary returnCode addressOfDataSourceName
  715.     addressOfActualLengthOfDataSourceName
  716.     addressOfDescriptionOfDataSourceName
  717.     addressOfActualLengthOfDescription
  718.     dataSourceName descriptionOfDataSourceName |
  719.  
  720.     addressOfDataSourceName
  721.         := WinAddress allocateMemory: SQLObject bufferSizeForName.
  722.     addressOfActualLengthOfDataSourceName
  723.         := WinAddress allocateMemory: SQLObject bufferSizeForName.
  724.     addressOfDescriptionOfDataSourceName
  725.         := WinAddress allocateMemory: SQLObject bufferSizeForName.
  726.     addressOfActualLengthOfDescription
  727.         := WinAddress allocateMemory: SQLObject bufferSizeForName.
  728.     dictionary := Dictionary new.
  729.     returnCode := SQLObject success.
  730.     [(returnCode == (SQLObject success)) or: [returnCode == (SQLObject successWithInfo)]]
  731.         whileTrue: [
  732.             returnCode := ODBCLibrary SQLDataSources: self handle asParameter
  733.                 with: SQLObject fetchNext asParameter
  734.                 with: addressOfDataSourceName asParameter
  735.                 with: SQLObject bufferSizeForName asParameter
  736.                 with: addressOfActualLengthOfDataSourceName asParameter
  737.                 with: addressOfDescriptionOfDataSourceName asParameter
  738.                 with: SQLObject bufferSizeForName asParameter
  739.                 with: addressOfActualLengthOfDescription asParameter.
  740.             ((returnCode == (SQLObject success)) or: [returnCode == (SQLObject successWithInfo)])
  741.                 ifTrue: [
  742.                     dataSourceName := String fromAddress: addressOfDataSourceName
  743.                                                 length: (WinLong fromAddress: addressOfActualLengthOfDataSourceName) asInteger.
  744.                     descriptionOfDataSourceName := String fromAddress: addressOfDescriptionOfDataSourceName
  745.                                     length: (WinLong fromAddress: addressOfActualLengthOfDescription) asInteger.
  746.                     dictionary at: dataSourceName put: descriptionOfDataSourceName].
  747.         ].
  748.     addressOfDataSourceName unlockAndFree.
  749.     addressOfActualLengthOfDataSourceName unlockAndFree.
  750.     addressOfDescriptionOfDataSourceName unlockAndFree.
  751.     addressOfActualLengthOfDescription unlockAndFree.
  752.     ^dictionary.!
  753.  
  754. free
  755.     "Relese all the memory space allocated by the receiver
  756.     and free all connections which are allocated by the receiver"
  757.     (self handle = nil)
  758.         ifTrue: [^self error: 'Already released.'].
  759.     connections do: [ :connection |
  760.         connection ~= nil ifTrue: [connection free]].
  761.     connections := nil.
  762.     ODBCLibrary SQLFreeEnv: self handle asParameter.
  763.     self handle: nil.!
  764.  
  765. handle
  766.     "Private"
  767.     ^henv!
  768.    
  769. handle: aHandle
  770.     "Private"
  771.     henv := aHandle!
  772.  
  773. remove: aConnection
  774.     "Private"
  775.     connections remove: aConnection! !
  776.  
  777.  
  778.  
  779. !SQLObject class methods !
  780.  
  781. allTypes
  782.     ^0!
  783.    
  784. assignBufferFor: anObject
  785.     | address |
  786.     (anObject isKindOf: String) ifTrue:[^WinAddress copyToNonSmalltalkMemory: anObject].
  787.     (anObject isKindOf: Integer) ifTrue:[
  788.         address := WinAddress allocateMemory: 4.
  789.         (WinLong fromInteger: anObject) copyToAddress: address.
  790.         ^address].
  791.     (anObject isKindOf: Float) ifTrue:[^WinAddress copyToNonSmalltalkMemory: anObject].!
  792.  
  793. bufferSizeForName
  794.     ^120!
  795.  
  796. char
  797.     "SQL type code, as defined in ANSI SQL 2
  798.     (Section 14.1, Table 18) "
  799.     ^1!
  800.  
  801. charInC
  802.     ^self char!
  803.  
  804. close
  805.     ^0!
  806.   
  807. columnCount
  808.     ^1!
  809.  
  810. columnDefinitionFor: aClass
  811.     (aClass inheritsFrom: String) ifTrue:[^256].
  812.     (aClass inheritsFrom: Integer) ifTrue:[^Integer base].
  813.     (aClass inheritsFrom: Float) ifTrue:[^nil].
  814.     ^nil!
  815.    
  816. columnLength
  817.     ^4!
  818.    
  819. columnName
  820.     ^2!
  821.  
  822. columnNulLable
  823.     ^7!
  824.  
  825. columnPrecision
  826.     ^5!
  827.  
  828. columnScale
  829.     ^6!
  830.  
  831. columnType
  832.     ^3!
  833.  
  834. commit
  835.     ^0!
  836.  
  837. cTypeFor: aClass
  838.     (aClass inheritsFrom: String) ifTrue:[^self charInC].
  839.     (aClass inheritsFrom: Integer) ifTrue:[^self shortInC].
  840.     (aClass inheritsFrom: Float) ifTrue:[^self doubleInC].
  841.     ^nil!
  842.  
  843. decimal
  844.     "SQL type code, as defined in ANSI SQL 2
  845.     (Section 14.1, Table 18) "
  846.     ^3!
  847.   
  848. double
  849.     "SQL type code, as defined in ANSI SQL 2
  850.     (Section 14.1, Table 18) "
  851.     ^8!
  852.    
  853. doubleInC
  854.     ^self double!
  855.  
  856. drop
  857.     ^1!
  858.    
  859. error
  860.  
  861.     ^-1!
  862.    
  863. false
  864.  
  865.     ^0!
  866.  
  867. fetchFirst
  868.  
  869.     ^2!
  870.    
  871. fetchNext
  872.  
  873.     ^1!
  874.  
  875. float
  876.     "SQL type code, as defined in ANSI SQL 2
  877.     (Section 14.1, Table 18) "
  878.     ^6!
  879.  
  880. floatInC
  881.     ^self real!
  882.    
  883. initialize
  884.     super initialize.
  885.     Smalltalk at:#SQLInfoConstants
  886.         ifAbsent: [Smalltalk at:#SQLInfoConstants put: Dictionary new].
  887.     SQLInfoConstants at: 'INFO_FIRST' put: 0.
  888.     SQLInfoConstants at: 'ACTIVE_CONNECTIONS' put: 0.
  889.     SQLInfoConstants at: 'ACTIVE_STATEMENTS' put: 1.
  890.     SQLInfoConstants at: 'DATA_SOURCE_NAME' put: 2.
  891.     SQLInfoConstants at: 'DRIVER_HDBC' put: 3.
  892.     SQLInfoConstants at: 'DRIVER_HENV' put: 4.
  893.     SQLInfoConstants at: 'DRIVER_HSTMT' put: 5.
  894.     SQLInfoConstants at: 'DRIVER_NAME' put: 6.
  895.     SQLInfoConstants at: 'DRIVER_VER' put: 7.
  896.     SQLInfoConstants at: 'FETCH_DIRECTION' put: 8.
  897.     SQLInfoConstants at: 'ODBC_API_CONFORMANCE' put: 9.
  898.     SQLInfoConstants at: 'ODBC_VER' put: 10.
  899.     SQLInfoConstants at: 'ROW_UPDATES' put: 11.
  900.     SQLInfoConstants at: 'ODBC_SAG_CLI_CONFORMANCE' put: 12.
  901.     SQLInfoConstants at: 'SERVER_NAME' put: 13.
  902.     SQLInfoConstants at: 'SEARCH_PATTERN_ESCAPE' put: 14.
  903.     SQLInfoConstants at: 'ODBC_SQL_CONFORMANCE' put: 15.
  904.     SQLInfoConstants at: 'DATABASE_NAME' put: 16.
  905.     SQLInfoConstants at: 'DBMS_NAME' put: 17.
  906.     SQLInfoConstants at: 'DBMS_VER' put: 18.
  907.     SQLInfoConstants at: 'ACCESSIBLE_TABLES' put: 19.
  908.     SQLInfoConstants at: 'ACCESSIBLE_PROCEDURES' put: 20.
  909.     SQLInfoConstants at: 'PROCEDURES' put: 21.
  910.     SQLInfoConstants at: 'CONCAT_NULL_BEHAVIOR' put: 22.
  911.     SQLInfoConstants at: 'CURSOR_COMMIT_BEHAVIOR' put: 23.
  912.     SQLInfoConstants at: 'CURSOR_ROLLBACK_BEHAVIOR' put: 24.
  913.     SQLInfoConstants at: 'DATA_SOURCE_READ_ONLY' put: 25.
  914.     SQLInfoConstants at: 'DEFAULT_TXN_ISOLATION' put: 26.
  915.     SQLInfoConstants at: 'EXPRESSIONS_IN_ORDERBY' put: 27.
  916.     SQLInfoConstants at: 'IDENTIFIER_CASE' put: 28.
  917.     SQLInfoConstants at: 'IDENTIFIER_QUOTE_CHAR' put: 29.
  918.     SQLInfoConstants at: 'MAX_COLUMN_NAME_LEN' put: 30.
  919.     SQLInfoConstants at: 'MAX_CURSOR_NAME_LEN' put: 31.
  920.     SQLInfoConstants at: 'MAX_OWNER_NAME_LEN' put: 32.
  921.     SQLInfoConstants at: 'MAX_PROCEDURE_NAME_LEN' put: 33.
  922.     SQLInfoConstants at: 'MAX_QUALIFIER_NAME_LEN' put: 34.
  923.     SQLInfoConstants at: 'MAX_TABLE_NAME_LEN' put: 35.
  924.     SQLInfoConstants at: 'MULT_RESULT_SETS' put: 36.
  925.     SQLInfoConstants at: 'MULTIPLE_ACTIVE_TXN' put: 37.
  926.     SQLInfoConstants at: 'OUTER_JOINS' put: 38.
  927.     SQLInfoConstants at: 'OWNER_TERM' put: 39.
  928.     SQLInfoConstants at: 'PROCEDURE_TERM' put: 40.
  929.     SQLInfoConstants at: 'QUALIFIER_NAME_SEPARATOR' put: 41.
  930.     SQLInfoConstants at: 'QUALIFIER_TERM' put: 42.
  931.     SQLInfoConstants at: 'SCROLL_CONCURRENCY' put: 43.
  932.     SQLInfoConstants at: 'SCROLL_OPTIONS' put: 44.
  933.     SQLInfoConstants at: 'TABLE_TERM' put: 45.
  934.     SQLInfoConstants at: 'TXN_CAPABLE' put: 46.
  935.     SQLInfoConstants at: 'USER_NAME' put: 47.
  936.     SQLInfoConstants at: 'CONVERT_FUNCTIONS' put: 48.
  937.     SQLInfoConstants at: 'NUMERIC_FUNCTIONS' put: 49.
  938.     SQLInfoConstants at: 'STRING_FUNCTIONS' put: 50.
  939.     SQLInfoConstants at: 'SYSTEM_FUNCTIONS' put: 51.
  940.     SQLInfoConstants at: 'TIMEDATE_FUNCTIONS' put: 52.
  941.     SQLInfoConstants at: 'CONVERT_BIGINT' put: 53.
  942.     SQLInfoConstants at: 'CONVERT_BINARY' put: 53.
  943.     SQLInfoConstants at: 'CONVERT_BIT' put: 55.
  944.     SQLInfoConstants at: 'CONVERT_CHAR' put: 56.
  945.     SQLInfoConstants at: 'CONVERT_DATE' put: 57.
  946.     SQLInfoConstants at: 'CONVERT_DECIMAL' put: 58.
  947.     SQLInfoConstants at: 'CONVERT_DOUBLE' put: 59.
  948.     SQLInfoConstants at: 'CONVERT_FLOAT' put: 60.
  949.     SQLInfoConstants at: 'CONVERT_INTEGER' put: 61.
  950.     SQLInfoConstants at: 'CONVERT_LONGVARCHAR' put: 62.
  951.     SQLInfoConstants at: 'CONVERT_NUMERIC' put: 63.
  952.     SQLInfoConstants at: 'CONVERT_REAL' put: 64.
  953.     SQLInfoConstants at: 'CONVERT_SMALLINT' put: 65.
  954.     SQLInfoConstants at: 'CONVERT_TIME' put: 66.
  955.     SQLInfoConstants at: 'CONVERT_TIMESTAMP' put: 67.
  956.     SQLInfoConstants at: 'CONVERT_TINYINT' put: 68.
  957.     SQLInfoConstants at: 'CONVERT_VARBINARY' put: 69.
  958.     SQLInfoConstants at: 'CONVERT_VARCHAR' put: 70.
  959.     SQLInfoConstants at: 'COVNERT_LONGVARBINARY' put: 71.
  960.     SQLInfoConstants at: 'TXN_ISOLATION_OPTION' put: 72.
  961.     SQLInfoConstants at: 'ODBC_SQL_OPT_IEF' put: 73.
  962.     SQLInfoConstants at: 'INFO_LAST' put: 73.
  963.     SQLInfoConstants at: 'INFO_DRIVER_START' put: 1000.!
  964.  
  965. integer
  966.     "SQL type code, as defined in ANSI SQL 2
  967.     (Section 14.1, Table 18) "
  968.     ^4!
  969.   
  970. longInC
  971.     ^self integer!
  972.  
  973. noDataFound
  974.  
  975.     ^100!
  976.  
  977. noNulls
  978.     ^0!
  979.  
  980. nts
  981.     ^-3!
  982.    
  983. nullable
  984.     ^1!
  985.    
  986. nullableUnknown
  987.     ^2!
  988.  
  989. nullData
  990.     ^-1!
  991.   
  992. nullHdbc
  993.  
  994.     ^0!
  995.  
  996. nullHenv
  997.  
  998.     ^0!
  999.  
  1000. nullHstmt
  1001.  
  1002.     ^0!
  1003.  
  1004. numeric
  1005.     "SQL type code, as defined in ANSI SQL 2
  1006.     (Section 14.1, Table 18) "
  1007.     ^2!
  1008.   
  1009. real
  1010.     "SQL type code, as defined in ANSI SQL 2
  1011.     (Section 14.1, Table 18) "
  1012.     ^7!
  1013.  
  1014. rollback
  1015.     ^1!
  1016.    
  1017. scaleFor: aClass
  1018.     (aClass inheritsFrom: String) ifTrue:[^nil].
  1019.     (aClass inheritsFrom: Integer) ifTrue:[^nil].
  1020.     (aClass inheritsFrom: Float) ifTrue:[^nil].
  1021.     ^nil!
  1022.    
  1023. shortInC
  1024.     ^self smallint!
  1025.    
  1026. smallint
  1027.     "SQL type code, as defined in ANSI SQL 2
  1028.     (Section 14.1, Table 18) "
  1029.     ^5!
  1030.  
  1031. SmalltalkClassFor: aSqlType
  1032.  
  1033.     aSqlType == (SQLObject char) ifTrue: [^String].
  1034.     aSqlType == (SQLObject numeric) ifTrue: [^String].
  1035.     aSqlType == (SQLObject decimal) ifTrue: [^String].
  1036.     aSqlType == (SQLObject integer) ifTrue: [^Integer].
  1037.     aSqlType == (SQLObject smallint) ifTrue: [^Integer].
  1038.     aSqlType == (SQLObject float) ifTrue: [^Float].
  1039.     aSqlType == (SQLObject real) ifTrue: [^Float].
  1040.     aSqlType == (SQLObject double) ifTrue: [^Float].
  1041.     aSqlType == (SQLObject varchar) ifTrue: [^String].!
  1042.    
  1043. sqlNullData
  1044.  
  1045.     ^-1!
  1046.  
  1047. sqlTypeFor: aClass
  1048.     (aClass inheritsFrom: String) ifTrue:[^self char].
  1049.     (aClass inheritsFrom: Integer) ifTrue:[^self integer].
  1050.     (aClass inheritsFrom: Float) ifTrue:[^self double].
  1051.     ^nil!
  1052.   
  1053. success
  1054.  
  1055.     ^0!
  1056.   
  1057. successWithInfo
  1058.  
  1059.     ^1!
  1060.   
  1061. true
  1062.  
  1063.     ^1!
  1064.  
  1065. varchar
  1066.     "SQL type code, as defined in ANSI SQL 2
  1067.     (Section 14.1, Table 18) "
  1068.     ^12! !
  1069.  
  1070.  
  1071.  
  1072. !SQLObject methods !
  1073.    
  1074. error
  1075.     "Answer an error info. related to the receiver."
  1076.    | henv hdbc hstmt addressOfErrorClass addressOfNativeErrorCode
  1077.         addressOfErrorMessage addressOfLengthOfAvailableMessage error |
  1078.     self class == SQLEnvironment
  1079.         ifTrue: [henv := self handle. hdbc := self nullHdbc. hstmt := self nullHstmt].
  1080.     self class == SQLConnection
  1081.         ifTrue: [henv := self environment handle. hdbc := self handle. hstmt := self class nullHstmt].
  1082.     self class == SQLStatement
  1083.         ifTrue: [henv := self connection environment handle.
  1084.                     hdbc := self connection handle. hstmt := self handle].
  1085.     addressOfErrorClass := WinAddress allocateMemory: self class bufferSizeForName.
  1086.     addressOfNativeErrorCode := WinAddress allocateMemory: 4.
  1087.     addressOfErrorMessage := WinAddress allocateMemory: self class bufferSizeForName.
  1088.     addressOfLengthOfAvailableMessage := WinAddress allocateMemory: 4.
  1089.     ODBCLibrary SQLError: henv asParameter
  1090.         with: hdbc asParameter
  1091.         with: hstmt asParameter
  1092.         with: addressOfErrorClass asParameter
  1093.         with: addressOfNativeErrorCode asParameter
  1094.         with: addressOfErrorMessage asParameter
  1095.         with: self class bufferSizeForName asParameter
  1096.         with: addressOfLengthOfAvailableMessage asParameter.
  1097.  
  1098.     error := Dictionary new.
  1099.     error at:#class put: (String fromAddress: addressOfErrorClass).
  1100.     error at:#nativeErrorCode put: (WinLong fromAddress: addressOfNativeErrorCode) asInteger.
  1101.     error at:#errorMessage put:(String fromAddress: addressOfErrorMessage).
  1102.     addressOfErrorClass unlockAndFree.
  1103.     addressOfNativeErrorCode unlockAndFree.
  1104.     addressOfErrorMessage unlockAndFree.
  1105.     addressOfLengthOfAvailableMessage unlockAndFree.
  1106.     ^error!
  1107.    
  1108. errorOnReturnedStringIsTooLong
  1109.  
  1110.     self error: 'Returned String is too long'.! !
  1111.  
  1112.  
  1113.  
  1114. !SQLColumns class methods !
  1115.   
  1116. allocateOn: aStatemente
  1117.     "Private"
  1118.     (aStatemente columns) == nil
  1119.         ifTrue: [^super new statement: aStatemente]
  1120.         ifFalse: [^nil]! !
  1121.  
  1122.  
  1123.  
  1124. !SQLColumns methods !
  1125.   
  1126. actualBytesTransferredToBufferAt: aColumn
  1127.     "Private"
  1128.     | address |
  1129.     address := (collection at: aColumn) at: #addressOfActualBytesTransferredToBuffer.
  1130.     ^(WinLong fromAddress: address) asInteger!
  1131.  
  1132. addressOfActualBytesTransferredToBufferAt: aColumn
  1133.     "Private"
  1134.     ^(collection at: aColumn) at: #addressOfActualBytesTransferredToBuffer.!
  1135.  
  1136. addressOfActualBytesTransferredToBufferAt: aColumn put: anAddress
  1137.     "Private"
  1138.     ^(collection at: aColumn) at: #addressOfActualBytesTransferredToBuffer put: anAddress.!
  1139.    
  1140. allocate: aNumberOfColumns
  1141.     "Private"
  1142.     collection := (Array new: aNumberOfColumns).
  1143.     1 to: collection size
  1144.         do: [ :i |
  1145.             self contents at: i put: Dictionary new
  1146.         ].
  1147.     self describeAllColumns; bindAllColumns.!
  1148.   
  1149. at: aColumn
  1150.     "Private"
  1151.     ^collection at: aColumn!
  1152.  
  1153. bindAllColumns
  1154.  
  1155.     "Assign storage and conversion for all columns."
  1156.  
  1157.     | size type |
  1158.     size := self size.
  1159.     1 to: size
  1160.         do: [ :n |
  1161.             type := self dataTypeInSQLAt: n.
  1162.             type ==  (SQLObject integer)
  1163.                 ifTrue: [self bindColumn: n with: SQLObject longInC with: 4].
  1164.             type == (SQLObject  char)
  1165.                 ifTrue: [self bindColumn: n with: SQLObject charInC
  1166.                                 with: ((self maximumLengthOrPrecisionAt: n) + 1)].
  1167.             type == (SQLObject  numeric)
  1168.                 ifTrue: [self bindColumn: n with: SQLObject charInC
  1169.                                 with: ((self maximumLengthOrPrecisionAt: n) + 1)].
  1170.             type == (SQLObject  decimal)
  1171.                 ifTrue: [self bindColumn: n with: SQLObject charInC
  1172.                                 with: ((self maximumLengthOrPrecisionAt: n) + 1)].
  1173.             type == (SQLObject  smallint)
  1174.                 ifTrue: [self bindColumn: n with: SQLObject shortInC
  1175.                                 with: 2].
  1176.             type == (SQLObject  float)
  1177.                 ifTrue: [self bindColumn: n with: SQLObject doubleInC
  1178.                                 with: 8].
  1179.             type == (SQLObject  real)
  1180.                 ifTrue: [self bindColumn: n with: SQLObject doubleInC
  1181.                                 with: 4].
  1182.             type == (SQLObject  double)
  1183.                 ifTrue: [self bindColumn: n with: SQLObject doubleInC
  1184.                                 with: 8].
  1185.              type == (SQLObject  varchar)
  1186.                 ifTrue: [self bindColumn: n with: SQLObject charInC
  1187.                                 with: (self maximumLengthOrPrecisionAt: n)].
  1188.        ].!
  1189.  
  1190. bindColumn: aColumnNumber
  1191.     with: aDataTypeInC
  1192.     with: aSizeOfBuffer
  1193.     "Private"
  1194.     self dataTypeInCAt: aColumnNumber put: aDataTypeInC.
  1195.     self bufferAt: aColumnNumber
  1196.         put: (WinAddress allocateMemory: aSizeOfBuffer).
  1197.     self addressOfActualBytesTransferredToBufferAt: aColumnNumber
  1198.         put: (WinAddress allocateMemory: 4).
  1199.     ODBCLibrary SQLBindCol:  statement handle asParameter
  1200.         with: aColumnNumber asParameter
  1201.         with: aDataTypeInC asParameter
  1202.         with: (self bufferAt: aColumnNumber) asParameter
  1203.         with: aSizeOfBuffer asParameter
  1204.         with: (self addressOfActualBytesTransferredToBufferAt: aColumnNumber) asParameter.!
  1205.  
  1206. bufferAt: aColumn
  1207.     "Private"
  1208.     ^(collection at: aColumn) at: #buffer!
  1209.  
  1210. bufferAt: aColumn put: anAddress
  1211.     "Private"
  1212.     ^(collection at: aColumn) at: #buffer put: anAddress!
  1213.   
  1214. collectAllData
  1215.         "Private"
  1216.     | col |
  1217.     col := OrderedCollection new.
  1218.     1 to: self size do: [ :i |
  1219.         col add: (self dataAt: i)].
  1220.     ^col!
  1221.    
  1222. collectAllName
  1223.         "Private"
  1224.     | col |
  1225.     col := OrderedCollection new.
  1226.     1 to: self size do: [ :i |
  1227.         col add: (self nameAt: i)].
  1228.     ^col!
  1229.    
  1230. collectAllType
  1231.         "Private"
  1232.     | col |
  1233.     col := OrderedCollection new.
  1234.     1 to: self size do: [ :i |
  1235.         col add: (self sqlTypeSymbolAt: i)].
  1236.     ^col!
  1237.   
  1238. columnAttributeMask: aColumnNumber
  1239.     "Private"
  1240.     | addressOfAttributeMask addressOfTypeName addressOfNumberOfCharactersInTypeName attributeMask |
  1241.  
  1242.     addressOfAttributeMask := WinAddress allocateMemory: 2.
  1243.     addressOfTypeName := WinAddress allocateMemory: SQLObject bufferSizeForName.
  1244.     addressOfNumberOfCharactersInTypeName := WinAddress allocateMemory: 2.
  1245.     "ODBCLibrary SQLColAttributes:  statement handle asParameter
  1246.         with: aColumnNumber asParameter
  1247.         with: addressOfAttributeMask asParameter
  1248.         with:  addressOfTypeName asParameter
  1249.         with: SQLObject bufferSizeForName asParameter
  1250.         with: addressOfNumberOfCharactersInTypeName asParameter"
  1251.     attributeMask := WinLong fromAddress: addressOfAttributeMask.
  1252.     addressOfAttributeMask unlockAndFree.
  1253.     addressOfTypeName unlockAndFree.
  1254.     addressOfNumberOfCharactersInTypeName unlockAndFree.
  1255.     ^attributeMask.!
  1256.  
  1257. columnAttributes: aColumnNumber with: aDescribeType
  1258.     "Private"
  1259.     self error: 'This API is not supported by ODBC.'!
  1260.    
  1261. columnTypeName: aColumnNumber
  1262.     "Private"
  1263.     | addressOfAttributeMask addressOfTypeName addressOfNumberOfCharactersInTypeName typeName |
  1264.  
  1265.     addressOfAttributeMask := WinAddress allocateMemory: 2.
  1266.     addressOfTypeName := WinAddress allocateMemory: SQLObject bufferSizeForName.
  1267.     addressOfNumberOfCharactersInTypeName := WinAddress allocateMemory: 2.
  1268.     "ODBCLibrary SQLColAttributes:  statement handle asParameter
  1269.         with: aColumnNumber asParameter
  1270.         with: addressOfAttributeMask asParameter
  1271.         with:  addressOfTypeName asParameter
  1272.         with: SQLObject bufferSizeForName asParameter
  1273.         with: addressOfNumberOfCharactersInTypeName asParameter"
  1274.     typeName := String fromAddress: addressOfTypeName length: (WinLong fromAddress: addressOfNumberOfCharactersInTypeName) asInteger.
  1275.     addressOfAttributeMask unlockAndFree.
  1276.     addressOfTypeName unlockAndFree.
  1277.     addressOfNumberOfCharactersInTypeName unlockAndFree.
  1278.     ^typeName.!
  1279.    
  1280. contents
  1281.     "Private"
  1282.     ^collection!
  1283.    
  1284. contents: anCollection
  1285.     "Private"
  1286.     collection := anCollection!
  1287.   
  1288. dataAt: aColumnNumber
  1289.     "Answer an object at aColumnNumber in the result."
  1290.  
  1291.     | type |
  1292.     ((self actualBytesTransferredToBufferAt: aColumnNumber)
  1293.         = SQLObject nullData)
  1294.         ifTrue: [
  1295.             ((self nullableAt: aColumnNumber)
  1296.                 = SQLObject nullable)
  1297.                 ifTrue: [^'null'] ifFalse: [^'?'].
  1298.         ].
  1299.  
  1300.     type := self dataTypeInSQLAt: aColumnNumber.
  1301.     type ==  (SQLObject integer)            "32bit"
  1302.         ifTrue: [^Integer fromAddress: (self bufferAt: aColumnNumber) length: 4].
  1303.     type == (SQLObject  char)
  1304.         ifTrue: [^String fromAddress: (self bufferAt: aColumnNumber)].
  1305.     type == (SQLObject  numeric)
  1306.         ifTrue: [^nil].
  1307.     type == (SQLObject  decimal)
  1308.         ifTrue: [^nil].
  1309.      type == (SQLObject  smallint)
  1310.         ifTrue: [^Integer fromAddress: (self bufferAt: aColumnNumber) length: 2].
  1311.      type == (SQLObject  float)
  1312.         ifTrue: [^nil].
  1313.     type == (SQLObject  real)
  1314.         ifTrue: [^nil].
  1315.     type == (SQLObject  double)
  1316.         ifTrue: [^Float fromAddress: (self bufferAt: aColumnNumber)].
  1317.     type == (SQLObject  varchar)
  1318.         ifTrue: [^String fromAddress: (self bufferAt: aColumnNumber)].!
  1319.  
  1320. dataTypeInCAt: aColumn
  1321.     "Private"
  1322.     ^(collection at: aColumn) at: #dataTypeInC!
  1323.   
  1324. dataTypeInCAt: aColumn put: anAddress
  1325.     "Private"
  1326.     ^(collection at: aColumn) at: #dataTypeInC put: anAddress!
  1327.  
  1328. dataTypeInSQLAt: aColumn
  1329.     "Answer a SQL data type at aColumn in the result."
  1330.     ^(collection at: aColumn) at: #dataTypeInSQL!
  1331.  
  1332. dataTypeInSQLAt: aColumn put: anObject
  1333.     "Private"
  1334.     ^(collection at: aColumn) at: #dataTypeInSQL put: anObject!
  1335.   
  1336. describeAllColumns
  1337.     "Private"
  1338.     1 to: self size do: [ :n |
  1339.         self describeColumn: n].!
  1340.  
  1341. describeColumn: aColumnNumber
  1342.     "Private"
  1343.     | addressOfDescriptorName addressOfNumberOfBytesAvailable addressOfDataTypeInSQL
  1344.      addressOfMaximumLengthOrPrecision addressOfScale addressOfNullable |
  1345.     addressOfDescriptorName := WinAddress allocateMemory: SQLObject bufferSizeForName.
  1346.     addressOfNumberOfBytesAvailable := WinAddress allocateMemory: 2.
  1347.     addressOfDataTypeInSQL :=  WinAddress allocateMemory: 2.
  1348.     addressOfMaximumLengthOrPrecision :=  WinAddress allocateMemory: 4.
  1349.     addressOfScale :=  WinAddress allocateMemory: 2.
  1350.     addressOfNullable :=  WinAddress allocateMemory: 2.
  1351.     ODBCLibrary SQLDescribeCol:  statement handle asParameter
  1352.         with: aColumnNumber asParameter
  1353.         with: addressOfDescriptorName asParameter
  1354.         with: SQLObject bufferSizeForName asParameter
  1355.         with: addressOfNumberOfBytesAvailable asParameter
  1356.         with: addressOfDataTypeInSQL asParameter
  1357.         with: addressOfMaximumLengthOrPrecision asParameter
  1358.         with: addressOfScale asParameter
  1359.         with: addressOfNullable asParameter.
  1360.  
  1361.     self nameAt: aColumnNumber
  1362.         put: (String fromAddress: addressOfDescriptorName length: (WinLong fromAddress: addressOfNumberOfBytesAvailable) asInteger).
  1363.     addressOfDescriptorName unlockAndFree.  addressOfNumberOfBytesAvailable unlockAndFree.
  1364.     self dataTypeInSQLAt: aColumnNumber
  1365.          put: (WinLong fromAddress: addressOfDataTypeInSQL) asInteger.
  1366.     addressOfDataTypeInSQL unlockAndFree.
  1367.     self maximumLengthOrPrecisionAt: aColumnNumber
  1368.         put: (WinLong fromAddress: addressOfMaximumLengthOrPrecision) asInteger.
  1369.     addressOfMaximumLengthOrPrecision unlockAndFree.
  1370.     self scaleAt: aColumnNumber
  1371.         put: (WinLong fromAddress: addressOfScale) asInteger.
  1372.     addressOfScale unlockAndFree.
  1373.     self nullableAt: aColumnNumber
  1374.         put: (WinLong fromAddress: addressOfNullable) asInteger.
  1375.     addressOfNullable unlockAndFree.
  1376.     ^self contents!
  1377.    
  1378. extendedFetch: aTypeOfFetch with: aNumberOfRowsActurallyFetched
  1379.     "Private"
  1380.     self error: ''!
  1381.  
  1382. fetch
  1383.     "Fetches a row of data from a result.
  1384.     Answer nil if failed."
  1385.     ((ODBCLibrary SQLFetch: statement handle asParameter) ~= self class success)
  1386.         ifTrue: [^nil]!
  1387.  
  1388. free
  1389.     "Release all the memory space allocated by teh receiver."
  1390.  
  1391.     1 to: collection size
  1392.         do: [ :n |
  1393.             (self bufferAt: n) == nil
  1394.                 ifTrue: []
  1395.                 ifFalse: [(self bufferAt: n) unlockAndFree]
  1396.             ].
  1397.     statement columns: nil!
  1398.    
  1399. getObjectAt: aColumnNumber
  1400.     "Private - Answer an object, picking up from output buffer."
  1401.  
  1402.     | type size addressOfBuffer addressOfTotalBytes string totalBytes |
  1403.     type := self dataTypeInSQLAt: aColumnNumber.
  1404.     size := self maximumLengthOrPrecisionAt: aColumnNumber.
  1405.     addressOfBuffer := WinAddress allocateMemory: size.
  1406.     addressOfTotalBytes := WinAddress allocateMemory: 4.
  1407.     type == (SQLObject varchar)
  1408.         ifTrue: [
  1409.             ODBCLibrary SQLGetData: statement handle
  1410.                 with: aColumnNumber asParameter
  1411.                 with: SQLObject char asParameter
  1412.                 with: addressOfBuffer asParameter
  1413.                 with: size asParameter
  1414.                 with: addressOfTotalBytes asParameter.
  1415.             totalBytes := (WinLong fromAddress: addressOfTotalBytes) asInteger.
  1416.             string := String fromAddress: addressOfBuffer length: totalBytes.
  1417.         ].
  1418.         addressOfTotalBytes unlockAndFree.
  1419.         addressOfBuffer unlockAndFree.
  1420.         ^string!
  1421.  
  1422. maximumLengthOrPrecisionAt: aColumn
  1423.     "Answer maximum length or precision at aColumn in the result."
  1424.     ^(collection at: aColumn) at: #maximumLengthOrPrecision!
  1425.    
  1426. maximumLengthOrPrecisionAt: aColumn put: anObject
  1427.     "Private"
  1428.     ^(collection at: aColumn) at: #maximumLengthOrPrecision put: anObject.!
  1429.    
  1430. nameAt: aColumn
  1431.     "Answer a column name at aColumn in the result."
  1432.     ^(collection at: aColumn) at: #name!
  1433.  
  1434. nameAt: aColumn put: aName
  1435.     "Private"
  1436.     ^(collection at: aColumn) at: #name put: aName!
  1437.   
  1438. nullableAt: aColumn
  1439.     "Private"
  1440.     ^(collection at: aColumn) at: #nullable!
  1441.  
  1442. nullableAt: aColumn put: anObject
  1443.     "Private"
  1444.     ^(collection at: aColumn) at: #nullable put: anObject!
  1445.  
  1446. scaleAt: aColumn
  1447.     "Answer a scale at aColumn in the result."
  1448.     ^(collection at: aColumn) at: #scale!
  1449.  
  1450. scaleAt: aColumn put: anObject
  1451.     "Private"
  1452.     ^(collection at: aColumn) at: #scale put: anObject!
  1453.   
  1454. size
  1455.     "Answer number of columns in the result."
  1456.     ^self contents size.!
  1457.   
  1458. sqlTypeSymbolAt:  aColumn
  1459.     "Answer an instance of Symbol for SQL data type
  1460.     at aColumn in the result."
  1461.     | number |
  1462.     number := (collection at: aColumn) at: #dataTypeInSQL.
  1463.     self class char = number
  1464.         ifTrue: [^#char].
  1465.     self class decimal = number
  1466.         ifTrue: [^#decimal].
  1467.     self class double = number
  1468.         ifTrue: [^#double].
  1469.     self class float = number
  1470.         ifTrue: [^#float].
  1471.     self class integer = number
  1472.         ifTrue: [^#integer].
  1473.     self class real = number
  1474.         ifTrue: [^#real].
  1475.     self class smallint = number
  1476.         ifTrue: [^#smallint].
  1477.     self class varchar = number
  1478.         ifTrue: [^#varchar].
  1479.     ^#unknown!
  1480.   
  1481. statement: aStatement
  1482.     "Private"
  1483.     statement := aStatement! !
  1484.  
  1485.  
  1486.  
  1487. !ODBCDLL class methods !
  1488.  
  1489. fileName
  1490.         "Answer the receiver's file name."
  1491.     ^'ODBC.DLL'!
  1492.   
  1493. startUp
  1494.         "Private - Load ODBCDLL."
  1495.     ODBCLibrary := ODBCDLL open.! !
  1496.  
  1497.  
  1498.  
  1499. !ODBCDLL methods !
  1500.    
  1501. SQLAllocConnect: henv with: phdbc
  1502.    "Core: SQLAllocConnect allocates memory for a connection handle
  1503.     within the environment identified by henv."
  1504.  
  1505.     <api: SQLAllocConnect ulong ulong short>
  1506.     ^self invalidArgument!
  1507.   
  1508. SQLAllocEnv: phenv
  1509.     "Core: SQLAllocEnv allocates memory for an environment handle and
  1510.     initializes the ODBC call-level interfaces for use by an appliction.
  1511.     An applicatin must call SQLAllocEnv prior to calling  any other ODBC funtion"
  1512.  
  1513.     <api: SQLAllocEnv ulong short>
  1514.     ^self invalidArgument!
  1515.  
  1516. SQLAllocStmt: hdbc with: phstmt
  1517.     "Core: SQLAllocStmt allocates memory for a statement handloe
  1518.     and associates the statement handle with the connection
  1519.     specified by hdbc."
  1520.  
  1521.     <api: SQLAllocStmt ulong ulong short>
  1522.     ^self invalidArgument!
  1523.  
  1524. SQLBindCol: hstmt with: icol with: fCType with: rgbValue with: cbValueMax with: pcbValue
  1525.      "Core: SQLBindCol assigns storage and conversions for a column
  1526.      in a result set, iincluding:
  1527.     * A storage buffer that will rceive the contents of a column of a column of data
  1528.     * The length of the storage buffer
  1529.     * A storage location that will receive the actual length of the column of data
  1530.         returned by the fetch operation
  1531.     * Data conversion
  1532.     SQLBindCol can also remove binding of columns that wrer previously bound,
  1533.     so that the application can call SQLGetData to retrieve data in the columns
  1534.     or to simply omit columns of the result set from the set of bound colums.
  1535.     Each time SQLFetch is called, the driver places the next row of the result set into the
  1536.     variables specified in previous calls to SQLBindCol for each column.
  1537.     To retrieve a column in portions (such as data in LONG VARCHAR types),
  1538.     call SQLGetData."
  1539.  
  1540.     <api: SQLBindCol ulong ushort short ulong long ulong short>
  1541.     ^self invalidArgument!
  1542.   
  1543. SQLCancel: hstmt
  1544.     "Core: SQLCancel requests cancellation of processing for an SQL statment
  1545.     and returns control to the application. If an application submits statements asychronously,
  1546.     it can call SQLCancel.
  1547.     Otherwise, the application cannot access SQLCancel from the Windows environment while
  1548.     a request is in process. If an application calls SQLCancel for a function called synchronously,
  1549.     SQLCancel has the same effect as SQLFreeStmt with the SQL_CLOSE option"
  1550.  
  1551.     <api: SQLCancel ulong short>
  1552.     ^self invalidArgument!
  1553.  
  1554. SQLColAttributes: hstmt with: icol with: pfAttributes with: szTypeName with: cbTypeNameMax with: pcbTypeName
  1555.     "Level 1: SQLColAttributes returns descriptive information -- beyond that provided
  1556.     by SQLDescribeCol -- for a column in the result set."
  1557.  
  1558.     <api: SQLColAttributes ulong ushort ulong ulong short ulong short>
  1559.     ^self invalidArgument!
  1560.    
  1561. SQLColumnPrivileges: hstmt with: szTableQualifier with: cbTableQualifier with: szTableOwner with: cbTableOwner with: szTableName with: cbTableName with: szColumnName with: cbColumnName
  1562.     "Level 2: SQLColumnPrivileges returns a list of columns
  1563.     and associated privileges for one or more tables.
  1564.     The driver returns the information as a result set on the specified hstmt."
  1565.  
  1566.     <api: SQLColumnPrivileges ulong struct short struct short struct short struct short short>
  1567.     ^self invalidArgument!
  1568.  
  1569. SQLColumns: hstmt with: szTableQualifier with: cbTableQualifier with: szTableOwner with: cbTableOwner with: szTableName with: cbTableName with: szColumnName with: cbColumnName
  1570.  
  1571.     "Level 1: SQLColumns returns the list of column names in secified tables.
  1572.     The driver returns this information as a result set on the specified hstmt."
  1573.  
  1574.     <api: SQLColumns ulong struct short struct short struct short struct short short>
  1575.     ^self invalidArgument!
  1576.  
  1577. SQLConnect: hdbc with: szDSN with: cbDSN with: szUID with: cbUID with: szAuthStr with: cbAuthStr
  1578.  
  1579.     "Core: SQLConnect loads a driver and establishes a connection to a data souce.
  1580.     The connection handle references storage of all information about the connection,
  1581.     including status, and error information."
  1582.  
  1583.     <api: SQLConnect ulong struct short struct short struct short short>
  1584.     ^self invalidArgument!
  1585.  
  1586. SQLDataSources: henv with: fDirection with: szDSN with: cbDSNMax with: pcbDSN
  1587.     with: szDescription with: cbDescriptionMax with: pcbDescription
  1588.  
  1589.     "Level 2: SQLDataSources enumerates data source names"
  1590.  
  1591.     <api: SQLDataSources ulong ushort ulong short ulong ulong short ulong short>
  1592.     ^self invalidArgument!
  1593.  
  1594. SQLDescribeCol: hstmt with: icol with: szColName with: cbColNameMax with: pcbColName with: pfSqlType with: pcbColDef with: pibScale with: pfNullable
  1595.  
  1596.     "Core: SQLDescribeCol returns the result descriptor -- column name, type, and length --
  1597.     for one column in the result set."
  1598.  
  1599.     <api: SQLDescribeCol ulong ushort ulong short ulong ulong ulong ulong ulong short>
  1600.     ^self invalidArgument!
  1601.    
  1602. SQLDescribeParam: hstmt with: ipar with: szColName with: cbColNameMax with: pcbColName with: pfSqlType with: pcbColDef with: pibScale with: pfNullable
  1603.  
  1604.     "Level 2: SQLDescribeParam returns the description of a parameter marker
  1605.     associated with a prepared SQL statement."
  1606.  
  1607.     <api: SQLDescribleParam ulong ushort ulong short ulong ulong ulong ulong ulong short>
  1608.     ^self invalidArgument!
  1609.  
  1610. SQLDisconnect: hdbc
  1611.  
  1612.     "Core: SQLDisconnect closes the connection associated with a specific connection handle."
  1613.  
  1614.     <api: SQLDisconnect ulong short>
  1615.     ^self invalidArgument!
  1616.  
  1617. SQLDriverConnect: hdbc with: hwnd with: szConnStrIn with: cbConnStrIn with: szConnStrOut with: cbConnStrOutMax with: pcbConnStrOUt with: fDriverCompletion
  1618.  
  1619.     "Level 2: SQLDriverConnect is an alternative to SQLConnect; it supports data sources
  1620.     that require connection fiformation other than teh three arguments used in SQLConnect"
  1621.  
  1622.     <api: SQLDriverConnect ulong ulong struct short ulong short ulong ushort short>
  1623.     ^self invalidArgument!
  1624.    
  1625. SQLError: henv with: hdbc with: hstmt with: szSqlState with: pfNativeError with: szErrorMsg with: cbErrorMsgMax with: pcbErrorMsg
  1626.  
  1627.     <api: SQLError ulong ulong ulong ulong ulong ulong short ulong short>
  1628.     ^self invalidArgument!
  1629.   
  1630. SQLExecDirect: hstmt with: szSqlStr with: cbSqlStr
  1631.  
  1632.     <api: SQLExecDirect ulong struct long short>
  1633.     ^self invalidArgument!
  1634.   
  1635. SQLExecute: hstmt
  1636.  
  1637.     <api: SQLExecute ulong short>
  1638.     ^self invalidArgument!
  1639.   
  1640. SQLExtendedFetch: hstmt with: fFetchType with: irow with: pcrow with: rgfRowStatus
  1641.  
  1642.     <api: SQLExtendedFetch ulong ushort long ulong  ulong short>
  1643.     ^self invalidArgument!
  1644.   
  1645. SQLFetch: hstmt
  1646.  
  1647.     <api: SQLFetch ulong short>
  1648.     ^self invalidArgument!
  1649.   
  1650. SQLForeignKeys: hstmt with: szPkTableQualifier with: cbPkTableQualifier with: szPkTableOwner with: cbPkTableOwner with: szPkTableName with: cbPkTableName with: szFkTableQualifier with: cbFkTableQualifier with: szFkTableOwner with: cbFkTableOwner with: szFkTableName with: cbFkTableName
  1651.  
  1652.     <api: SQLForeignKeys ulong struct short struct short struct short struct short struct short struct short short>
  1653.     ^self invalidArgument!
  1654.  
  1655. SQLFreeConnect: ulong
  1656.  
  1657.     <api: SQLFreeConnect ulong short>
  1658.     ^self invalidArgument!
  1659.   
  1660. SQLFreeEnv: henv
  1661.  
  1662.     <api: SQLFreeEnv ulong short>
  1663.     ^self invalidArgument!
  1664.    
  1665. SQLFreeStmt: hstmt with: fOption
  1666.  
  1667.     <api: SQLFreeStmt ulong ushort short>
  1668.     ^self invalidArgument!
  1669.    
  1670. SQLGetConnectOption: hdbc with: fOption with: pvParam
  1671.  
  1672.     <api: SQLGetConnectOption ulong ushort ulong short>
  1673.     ^self invalidArgument!
  1674.  
  1675. SQLGetCursorName: hstmt with: szCursor with: cbCursorMax with: pcbCursor
  1676.  
  1677.     <api: SQLGetCursorName ulong ulong short ulong short>
  1678.     ^self invalidArgument!
  1679.    
  1680. SQLGetData: hstmt with: icol with: fCType with: rgbValue with: cbValueMax with: pcbValue
  1681.  
  1682.     <api: SQLGetData ulong ushort short ulong long ulong short>
  1683.     ^self invalidArgument!
  1684.  
  1685. SQLGetFunctions: hdbc with: fFunction with: pfExists
  1686.  
  1687.     <api: SQLGetFunction ulong ushort ulong short>
  1688.     ^self invalidArgument!
  1689.   
  1690. SQLGetInfo: hdbc with: fInfoType
  1691.     with: rgbInfoValue with: cbInfoValueMax with: pcbInfoValue
  1692.  
  1693.     <api: SQLGetInfo ulong ushort ulong short ulong short>
  1694.     ^self invalidArgument!
  1695.   
  1696. SQLGetStmtOption: hstmt with: fOption with: pvParam
  1697.  
  1698.     <api: SQLGetStmtOption ulong ushort ulong short>
  1699.     ^self invalidArgument!
  1700.  
  1701. SQLGetTypeInfo: hstmt with: fSqlType
  1702.  
  1703.     <api: SQLGetTypeInfo ulong short short>
  1704.     ^self invalidArgument!
  1705.  
  1706. SQLMoreResults: hstmt
  1707.  
  1708.     <api: SQLMoreResults ulong short>
  1709.     ^self invalidArgument!
  1710.   
  1711. SQLNativeSql: hdbc with: szSqlStrIn with: cbSqlStrIn with: szSqlstr with: cbSqlStrMax with: pcbSqlStr
  1712.  
  1713.     <api: SQLNativeSql ulong struct long ulong long ulong short>
  1714.     ^self invalidArgument!
  1715.    
  1716. SQLNumParams: hstmt with: pcpar
  1717.  
  1718.     <api: SQLNumParams ulong ulong short>
  1719.     ^self invalidArgument!
  1720.  
  1721. SQLNumResultCols: hstmt with: pccol
  1722.  
  1723.     <api: SQLNumResultCols ulong ulong short>
  1724.     ^self invalidArgument!
  1725.  
  1726. SQLParamData: hstmt with: rgbValue
  1727.  
  1728.     <api: SQLParamData ulong ulong short>
  1729.     ^self invalidArgument!
  1730.  
  1731. SQLParamOptions: hstmt with: crow with: pirow
  1732.  
  1733.     <api: SQLParamOption ulong ulong ulong short>
  1734.     ^self invalidArgument!
  1735.   
  1736. SQLPrepare: hstmt with: szSqlStr with: cbSqlStr
  1737.  
  1738.     <api: SQLPrepare ulong struct long short>
  1739.     ^self invalidArgument!
  1740.  
  1741. SQLPrimaryKeys: hstmt with: szTableQualifier with: cbTableQualifier with: szTableOwner with: cbTableOwner with: szTableName with: cbTableName
  1742.  
  1743.     <api: SQLPrimaryKeys ulong struct short struct short struct short short>
  1744.     ^self invalidArgument!
  1745.    
  1746. SQLPutData: hstmt with: rgbValue with: cbValue
  1747.  
  1748.     <api: SQLPutData ulong ulong long short>
  1749.     ^self invalidArgument!
  1750.   
  1751. SQLRowCount: hstmt with: pcrow
  1752.  
  1753.     <api: SQLRowCount ulong ulong short>
  1754.     ^self invalidArgument!
  1755.   
  1756. SQLSetConnectOption: hdbc with: fOption with: vParam
  1757.  
  1758.     <api: SQLSetConnectOption ulong ushort ulong short>
  1759.     ^self invalidArgument!
  1760.  
  1761. SQLSetCursorName: hstmt with: szCursor with: cbCursor
  1762.  
  1763.     <api: SQLSetCursorName ulong struct short short>
  1764.     ^self invalidArgument!
  1765.    
  1766. SQLSetParam: hstmt with: ipar with: fCType with: fSqlType
  1767.     with: cbColDef with: ibScale with: rgbValue with: pcbValue
  1768.  
  1769.     <api: SQLSetParam ulong ushort short short ulong short ulong ulong short>
  1770.     ^self invalidArgument!
  1771.   
  1772. SQLSetPos: hstmt with: irow with: fRefresh with: fLock
  1773.  
  1774.     <api: SQLSetPos ulong ushort boolean boolean short>
  1775.     ^self invalidArgument!
  1776.    
  1777. SQLSetScrollOptions: hstmt with: fConcurrency with: crowKeyset with: crowRowset
  1778.  
  1779.     <api: SQLSetScrollOptions ulong ushort long ushort short>
  1780.     ^self invalidArgument!
  1781.  
  1782. SQLSetStmtOption: hstmt with: fOption with: vParam
  1783.  
  1784.     <api: SQLSetStmtOption ulong ushort ulong short>
  1785.     ^self invalidArgument!
  1786.   
  1787. SQLSpecialColumns: hstmt with: fColtype with: szTableQualifier with: cbTableQualifier with: szTableOwner with: cbTaleOwner with: szTableName with: cbTableName with: fScope
  1788.  
  1789.     <api: SQLSpecialColumns ulong ushort struct short struct short struct short ushort short>
  1790.     ^self invalidArgument!
  1791.  
  1792. SQLStatistics: hstmt with: szTableQualifier with: cbTableQualifier with: szTableOwner with: cbTaleOwner with: szTableName with: cbTableName with: fUnique with: fAccuracy
  1793.  
  1794.     <api: SQLStatistics ulong struct short struct short struct short ushort ushort short>
  1795.     ^self invalidArgument!
  1796.   
  1797. SQLTablePrivileges: hstmt
  1798.     with: szTableQualifier with: cbTableQualifier
  1799.     with: szTableOwner with: cbTableOwner
  1800.     with: szTableName with: cbTableName
  1801.  
  1802.     <api: SQLTablePrivileges ulong struct short struct short struct short short>
  1803.     ^self invalidArgument!
  1804.  
  1805. SQLTables: hstmt with: szTableQualifier with: cbTableQualifier
  1806.     with: szTableOwner with: cbTableOwner
  1807.     with: szTableName with: cbTableName
  1808.     with: szTableType with: cbTableType
  1809.  
  1810.     <api: SQLTables ulong struct short struct short struct short struct short short>
  1811.     ^self invalidArgument!
  1812.  
  1813. SQLTransact: henv with: hdbc with: fType
  1814.     <api: SQLTransact ulong ulong ushort short>
  1815.     ^self invalidArgument! !
  1816.  
  1817.  
  1818. !SystemDictionary methods !  
  1819. startUp
  1820.         "Private - Initiate a Smalltalk/V session and execute
  1821.          the 'go' file."
  1822.     | f |
  1823.     Process enableInterrupts: false.
  1824.     CurrentEvents := OrderedCollection new.
  1825.     WIN := WinInfo new.
  1826.     WIN getIt.
  1827.     KernelLibrary := WIN kernelHandle.
  1828.     UserLibrary := UserDLL getHandle.
  1829.     GDILibrary := GDIDLL getHandle.
  1830.     KeyboardLibrary := KeyboardDLL getHandle.
  1831.     VWVMLibrary := VWVMDLL open.
  1832.     NationalLanguage := NationalLanguageSupport new.
  1833.     Float startUp.
  1834.     WinLogicalObject initObjects.
  1835.     OriginalScreenExtent := Display extent.
  1836.     OriginalSysFontSize := SysFont charSize.
  1837.     Screen initialize.
  1838.     Bitmap initialize.
  1839.     Font initialize.
  1840.     Font allInstancesPrim do:[:font | font initFontHandle].
  1841.     Notifier initializeWindowHandles.
  1842.     GraphicsTool initialize.
  1843.     Smalltalk at: #OldScreenMode
  1844.         put: (Array new: 5).
  1845.     CursorManager initialize.
  1846.     WinMsgNS :=   WinMessage new.
  1847.     WinMsgNS contents:
  1848.         (KernelLibrary globalLock:
  1849.             (KernelLibrary globalAlloc: 0 bytes: 30)).
  1850.     PoppedModelessWindows := OrderedCollection new.
  1851.     Process enableInterrupts: true.
  1852.     Processor initialize.
  1853.     Sources := Array new: 3.
  1854.     Disk := Directory current.
  1855.     FileHandle initHandles.
  1856.     DialogBox initialize.
  1857.     FileDialog initialize.
  1858.     Terminal font: SysFont.
  1859.     CallBack startUp.
  1860.     HelpManager startUp.
  1861.     Icon startUp.
  1862.     AbortProcDLL startUp.
  1863.     ODBCDLL startUp.
  1864.     self notifyStartUpObjects.
  1865.     f := Disk file: 'go'.
  1866.     f size > 0
  1867.         ifTrue: [f fileIn; close]
  1868.         ifFalse: [f close. File remove: f pathName].
  1869.     Smalltalk isRunTime ifFalse: [
  1870.         ((Sources at: 1) isNil and: [FileHandle isThere: (File fullPathName:'sources.sml')])
  1871.             ifTrue: [
  1872.                 Sources at: 1 put: (File pathNameReadOnly: 'sources.sml')].
  1873.         (Sources at: 2) isNil ifTrue: [
  1874.             Sources at: 2 put: (File pathName: 'change.log')].
  1875.         (Sources at: 3) isNil ifTrue: [
  1876.             Sources at: 3 put: (self openDllSource)]].
  1877.  
  1878.     self closeSignOn.
  1879.  
  1880.     Notifier resume.
  1881.     Smalltalk isRunTime ifTrue: [
  1882.         self changeRuntimeIcon].
  1883.  
  1884.     "Opening of SmalltalkEmulator and SystemWindow is done in
  1885.     Notifier resume now."
  1886.  
  1887.     Notifier startRun! !
  1888.  
  1889. !Integer class methods ! 
  1890. fromAddress: anAddress length: aSize
  1891.         "comment"
  1892.     | winStruct |
  1893.     winStruct := (WinStructure new: aSize).
  1894.     winStruct fillFromAddress: anAddress.
  1895.     aSize = 0
  1896.         ifTrue: [^nil].
  1897.     aSize <= 1
  1898.         ifTrue: [^winStruct byteAtOffset: 0].
  1899.     aSize <= 2
  1900.         ifTrue: [^winStruct shortAtOffset: 0].
  1901.     aSize <= 4
  1902.         ifTrue: [^winStruct longAtOffset: 0].
  1903.     aSize > 4
  1904.         ifTrue: [^nil]!    !
  1905.  
  1906. !Float class methods !   
  1907. fromAddress: anAddress
  1908.  
  1909.     | winDouble result |
  1910.     winDouble := (WinStructure new: 8) fillFromAddress: anAddress.
  1911.     result := Float fromInteger: 0.
  1912.     1 to: 8 do: [ :i |
  1913.         result at: i put: (winDouble contents at: i)].
  1914.     ^result!   !
  1915. "construct application"
  1916. ((Smalltalk at: #Application ifAbsent: [])
  1917.     isKindOf: Class) ifTrue: [
  1918.         ((Smalltalk at: #Application) for:'ODBC Interface')
  1919.             addClass: SQLStatement;
  1920.             addClass: SQLConnection;
  1921.             addClass: SQLEnvironment;
  1922.             addClass: SQLObject;
  1923.             addClass: SQLColumns;
  1924.             addClass: ODBCDLL;
  1925.             addMethod: #fromAddress:length: forClass: Integer class;
  1926.             addMethod: #fromAddress: forClass: Float class;
  1927.             addMethod: #startUp forClass: SystemDictionary;
  1928.             comments: nil;
  1929.             initCode: 'Smalltalk at:#SQLInfoConstants
  1930.     ifAbsent: [Smalltalk at:#SQLInfoConstants put: Dictionary new].
  1931. ';
  1932.             finalizeCode: 'SQLObject initialize
  1933. ';
  1934.             startUpCode: '
  1935. ']!
  1936.  
  1937. "Finalize"
  1938.   
  1939. SQLObject initialize
  1940. !
  1941. Transcript cr; nextPutAll: 'ODBC Interface installed'; cr. !